/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.javahispano.javacup.tacticas.jvc2012.cavadores;

import java.awt.Color;
import java.util.LinkedList;
import org.javahispano.javacup.model.*;
import org.javahispano.javacup.model.util.*;
import org.javahispano.javacup.render.EstiloUniforme;
import org.javahispano.javacup.model.command.*;
import org.javahispano.javacup.model.engine.GameSituations;
import java.util.List;
import java.util.Random;

public class Cavadores implements Tactic {

    Position alineacion1[] = new Position[]{
        new Position(0.2595419847328244, -50.41044776119403),
        new Position(28.531468531468533, -32.30769230769231),
        new Position(-25.678321678321677, -32.07013574660634),
        new Position(9.034965034965035, -31.357466063348415),
        new Position(-5.706293706293707, -31.59502262443439),
        new Position(0.23776223776223776, -19.95475113122172),
        new Position(-11.65034965034965, -11.64027149321267),
        new Position(14.027972027972028, -13.540723981900454),
        new Position(0.951048951048951, -7.601809954751132),
        new Position(-1.6643356643356644, -0.23755656108597287),
        new Position(2.13986013986014, 0.0)
    };
    Position alineacion2[] = new Position[]{
        new Position(0.2595419847328244, -50.41044776119403),
        new Position(25.916083916083913, -31.83257918552036),
        new Position(-24.48951048951049, -31.357466063348415),
        new Position(9.748251748251748, -35.15837104072398),
        new Position(-6.181818181818182, -35.39592760180996),
        new Position(0.4755244755244755, -19.2420814479638),
        new Position(-12.601398601398602, -17.816742081447966),
        new Position(14.503496503496503, -18.529411764705884),
        new Position(-0.4755244755244755, -10.927601809954751),
        new Position(-6.6573426573426575, -6.889140271493213),
        new Position(7.132867132867133, -6.889140271493213)
    };
    Position alineacion3[] = new Position[]{
        new Position(0.2595419847328244, -50.41044776119403),
        new Position(28.531468531468533, -29.93212669683258),
        new Position(-28.76923076923077, -31.59502262443439),
        new Position(11.174825174825173, -30.16968325791855),
        new Position(-9.034965034965035, -29.93212669683258),
        new Position(0.4755244755244755, -16.153846153846153),
        new Position(-14.265734265734267, 3.5633484162895925),
        new Position(15.93006993006993, 2.8506787330316743),
        new Position(-1.6643356643356644, 19.95475113122172),
        new Position(7.37062937062937, 34.44570135746606),
        new Position(-9.034965034965035, 35.15837104072398)
    };

    private Position[] obtenerPosicionDelanteroRival(Position[] rivalPlayers) {
        double y1 = 50;
        double y2 = 50;
        double y3 = 50;
        double y4 = 50;
        Position[] posiciones = new Position[4];
        int aux1 = 0;
        int aux2 = 0;
        int aux3 = 0;
        int aux4 = 0;
        for (int i = 1; i < rivalPlayers.length; i++) {
            //System.out.println("rival " + i + " " + rivalPlayers[i]);
            if (rivalPlayers[i].getY() <= y1) {
                if (rivalPlayers[i].getY() <= y2) {
                    if (rivalPlayers[i].getY() <= y3) {
                        if (rivalPlayers[i].getY() <= y4) {
                            y4 = rivalPlayers[i].getY();
                            y3 = rivalPlayers[aux4].getY();
                            y2 = rivalPlayers[aux3].getY();
                            y1 = rivalPlayers[aux2].getY();
                            aux1 = aux2;
                            aux2 = aux3;
                            aux3 = aux4;
                            aux4 = i;
                        } else {
                            y3 = rivalPlayers[i].getY();
                            y2 = rivalPlayers[aux3].getY();
                            y1 = rivalPlayers[aux2].getY();
                            aux1 = aux2;
                            aux2 = aux3;
                            aux3 = i;
                        }
                    } else {
                        y2 = rivalPlayers[i].getY();
                        y1 = rivalPlayers[aux3].getY();
                        aux1 = aux2;
                        aux2 = i;
                    }
                } else {
                    y1 = rivalPlayers[i].getY();
                    aux1 = i;
                }
            }
            //   System.out.println(aux1 + " " + aux2 + " " + aux3 + " " + aux4 + " ");
        }
        posiciones[0] = rivalPlayers[aux1];
        posiciones[1] = rivalPlayers[aux2];
        posiciones[2] = rivalPlayers[aux3];
        posiciones[3] = rivalPlayers[aux4];

        return posiciones;
    }

    class TacticDetailImpl implements TacticDetail {

        public String getTacticName() {
            return "Los cavadores de hoyos";
        }

        public String getCountry() {
            return "España";
        }

        public String getCoach() {
            return "clemente";
        }

        public Color getShirtColor() {
            return new Color(204, 0, 0);
        }

        public Color getShortsColor() {
            return new Color(51, 51, 255);
        }

        public Color getShirtLineColor() {
            return new Color(0, 0, 0);
        }

        public Color getSocksColor() {
            return new Color(255, 255, 255);
        }

        public Color getGoalKeeper() {
            return new Color(255, 255, 0);
        }

        public EstiloUniforme getStyle() {
            return EstiloUniforme.FRANJA_DIAGONAL;
        }

        public Color getShirtColor2() {
            return new Color(153, 255, 0);
        }

        public Color getShortsColor2() {
            return new Color(102, 255, 51);
        }

        public Color getShirtLineColor2() {
            return new Color(51, 255, 0);
        }

        public Color getSocksColor2() {
            return new Color(255, 255, 255);
        }

        public Color getGoalKeeper2() {
            return new Color(186, 19, 242);
        }

        public EstiloUniforme getStyle2() {
            return EstiloUniforme.FRANJA_DIAGONAL;
        }

        class JugadorImpl implements PlayerDetail {

            String nombre;
            int numero;
            Color piel, pelo;
            double velocidad, remate, presicion;
            boolean portero;
            Position Position;

            public JugadorImpl(String nombre, int numero, Color piel, Color pelo,
                    double velocidad, double remate, double presicion, boolean portero) {
                this.nombre = nombre;
                this.numero = numero;
                this.piel = piel;
                this.pelo = pelo;
                this.velocidad = velocidad;
                this.remate = remate;
                this.presicion = presicion;
                this.portero = portero;
            }

            public String getPlayerName() {
                return nombre;
            }

            public Color getSkinColor() {
                return piel;
            }

            public Color getHairColor() {
                return pelo;
            }

            public int getNumber() {
                return numero;
            }

            public boolean isGoalKeeper() {
                return portero;
            }

            public double getSpeed() {
                return velocidad;
            }

            public double getPower() {
                return remate;
            }

            public double getPrecision() {
                return presicion;
            }
        }

        public PlayerDetail[] getPlayers() {
            return new PlayerDetail[]{
                        new JugadorImpl("courtois", 1, new Color(255, 204, 204), new Color(0, 0, 0), 1.0d, 0.88d, 0.5d, true),
                        new JugadorImpl("salgado", 2, new Color(255, 200, 150), new Color(255, 204, 0), 1.0d, 0.73d, 0.55d, false),
                        new JugadorImpl("abidal", 3, new Color(0, 0, 0), new Color(50, 0, 0), 1.0d, 0.73d, 0.55d, false),
                        new JugadorImpl("hierro", 4, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.72d, 0.55d, false),
                        new JugadorImpl("helguera", 5, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.74d, 0.55d, false),
                        new JugadorImpl("gatuso", 6, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.76d, 0.5d, false),
                        new JugadorImpl("seedorf", 7, new Color(0, 0, 0), new Color(0, 0, 0), 1.0d, 0.83d, 0.54d, false),
                        new JugadorImpl("diego ribas", 8, new Color(255, 255, 255), new Color(50, 0, 0), 1.0d, 0.83d, 0.54d, false),
                        new JugadorImpl("raul", 9, new Color(255, 204, 204), new Color(50, 0, 0), 1.0d, 1.0d, 1.0d, false),
                        new JugadorImpl("crouch", 10, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 1.0d, 1.0d, false),
                        new JugadorImpl("vieri", 11, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 1.0d, 1.0d, false)
                    };
        }
    }
    TacticDetail detalle = new TacticDetailImpl();

    public TacticDetail getDetail() {
        return detalle;
    }

    public Position[] getStartPositions(GameSituations sp) {
        return alineacion1;
    }

    public Position[] getNoStartPositions(GameSituations sp) {
        return alineacion2;
    }
    //Lista de Commands
    LinkedList<Command> comandos = new LinkedList<Command>();
    int cont;
    boolean activarZigZag = false;
    double[] zigzageñosX = {-40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40};

    @Override
    public List<Command> execute(GameSituations sp) {
//Limpia la lista de comandos
        comandos.clear();
        //Obtiene las posiciones de tus jugadores
        Position[] jugadores = sp.myPlayers();
        Position[] posicionDelanterosRivales = obtenerPosicionDelanteroRival(sp.rivalPlayers());
        for (int i = 0; i < jugadores.length; i++) {
            if (i > 0 && i < 5) {
                if (posicionDelanterosRivales[4 - i].getY() > -42) {
                    comandos.add(new CommandMoveTo(i, new Position(posicionDelanterosRivales[4 - i].getX(), posicionDelanterosRivales[4 - i].getY() - 1)));
                } else {
                    comandos.add(new CommandMoveTo(i, new Position(posicionDelanterosRivales[4 - i].getX(), posicionDelanterosRivales[4 - i].getY())));

                }
            } else if (i == 5) {
                comandos.add(new CommandMoveTo(5, sp.ballPosition()));
            } else if (i == 6 || i == 7) {
                Random r = new Random();
                Position posicion;
                if (r.nextBoolean()) {
                    posicion = new Position(alineacion3[i]);
                } else {
                    posicion = new Position(alineacion3[i].getX() + r.nextInt(30) - 15, alineacion3[i].getY() + r.nextInt(30) - 15);
                }
                comandos.add(new CommandMoveTo(i, posicion));
            } else {
                //Ordena a cada jugador que se ubique segun la alineacion1
                Random r = new Random();
                Position posicion;
                if (r.nextBoolean()) {
                    posicion = new Position(alineacion3[i]);
                } else {
                    posicion = new Position(alineacion3[i].getX() + r.nextInt(30 * 2) - 30, alineacion3[i].getY() + r.nextInt(30 * 2) - 30);
                }
                comandos.add(new CommandMoveTo(i, posicion));
            }
        }
        //Si no saca el rival
        if (!sp.isRivalStarts()) {
            //Obtiene los datos de recuperacion del balon
            int[] recuperadores = sp.getRecoveryBall();
            //Si existe posibilidad de recuperar el balon
            if (recuperadores.length > 1) {
                //Obtiene las coordenadas del balon en el instante donde
                //se puede recuperar el balon
                double[] posRecuperacion = sp.getTrajectory(recuperadores[0]);
                //Recorre la lista de jugadores que pueden recuperar
                for (int i = 1; i < recuperadores.length; i++) {
                    //Ordena a los jugadores recuperadores que se ubique
                    //en la posicion de recuperacion
                    if (recuperadores[i] > 4) {
                        comandos.add(new CommandMoveTo(recuperadores[i],
                                new Position(posRecuperacion[0], posRecuperacion[1])));
                    } else if (recuperadores[i] == 0) {
                        double x = posRecuperacion[0];
                        double y = posRecuperacion[1];
                        if (posRecuperacion[0] < -8) {
                            x = -8;
                        }
                        if (posRecuperacion[0] > 8) {
                            x = 8;
                        }
                        if (posRecuperacion[1] > -46) {
                            y = -46;
                        }
                        comandos.add(new CommandMoveTo(0, new Position(x, y)));
                    } else if (recuperadores[i] > 2) {
                        comandos.add(new CommandMoveTo(recuperadores[i],
                                new Position(posRecuperacion[0], posRecuperacion[1])));
                        //  int aux = i;
                        //  while (aux < 5) {
                        //      comandos.add(new CommandMoveTo(aux+1,
                        //              posicionDelanterosRivales[4 - aux]));
                        //      aux++;
                        //  }
                    }
                }
            }
        }
        //Instancia un generador aleatorio
        Random r = new Random();
        //Recorre la lista de mis jugadores que pueden rematar
        for (int i : sp.canKick()) {
            //Si el jugador es de indice 9 10 11
            if (i == 10 || i == 9 || i == 8) {
                //condicion aleatoria
                if (i == 8) {
                    if (r.nextBoolean()) {
                        comandos.add(new CommandHitBall(i, sp.myPlayers()[9], 0.5, 12));
                    } else {
                        comandos.add(new CommandHitBall(i, sp.myPlayers()[10], 0.5, 12));
                    }
                }
                if (i == 9 || i == 10) {
                    //Ordena que debe rematar al centro del arco
                    if (sp.ballPosition().getX() < -20) {
                        comandos.add(new CommandHitBall(i, sp.myPlayers()[9], 1, 25));
                    } else if (sp.ballPosition().getX() > 20) {
                        comandos.add(new CommandHitBall(i, sp.myPlayers()[10], 1, 25));
                    } else {
                        comandos.add(new CommandHitBall(i, Constants.centroArcoSup, 1, 12 + r.nextInt(4)));
                    }
                }
            } else if (i == 0) {
                //Ordena que debe pasar a Raul
                comandos.add(new CommandHitBall(i, sp.myPlayers()[8], 1, 45));
            } else if (i == 1 || i == 2 || i == 3 || i == 4) {
                if (r.nextBoolean()) {
                    comandos.add(new CommandHitBall(i, sp.myPlayers()[5], 1, 20));
                } else {
                    comandos.add(new CommandHitBall(i, sp.myPlayers()[6], 1, 20));
                }

            } else {
                if (i == 6 && sp.ballPosition().getY() > 25) {
                    comandos.add(new CommandHitBall(i, Constants.centroArcoSup, 1, 12 + r.nextInt(6)));
                }
                //pase a raul adelantado
                if (r.nextBoolean()) {
                    comandos.add(new CommandHitBall(i, new Position(sp.myPlayers()[9].getX(), sp.myPlayers()[9].getY()), 1, 40));
                } else {
                    comandos.add(new CommandHitBall(i, new Position(sp.myPlayers()[10].getX(), sp.myPlayers()[9].getY()), 1, 40));
                }
            }
        }
        //Retorna la lista de comandos
        return comandos;
    }
}